package keys

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/leaanthony/slicer"
)

var namedKeys = slicer.String([]string{"backspace", "tab", "return", "enter", "escape", "left", "right", "up", "down", "space", "delete", "home", "end", "page up", "page down", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32", "f33", "f34", "f35", "numlock"})

func parseKey(key string) (string, bool) {
	// Lowercase!
	key = strings.ToLower(key)

	// Check special case
	if key == "plus" {
		return "+", true
	}

	// Handle named keys
	if namedKeys.Contains(key) {
		return key, true
	}

	// 检查我们只有一个字符
	if len(key) != 1 {
		return "", false
	}

	runeKey := rune(key[0])

	// 这可能过于包容
	if strconv.IsPrint(runeKey) {
		return key, true
	}

	return "", false
}


// ff:
// shortcut:
func Parse(shortcut string) (*Accelerator, error) {
	var result Accelerator

	// 通过 + 分割快捷方式
	components := strings.Split(shortcut, "+")

// 如果我们只有一个元素，那么它应该是一个键
// 我们需要组件
	if len(components) == 0 {
		return nil, fmt.Errorf("no components given to validateComponents")
	}

	// 记录我们已处理过的修饰符
	var modifiersProcessed slicer.StringSlicer

	// Check components
	for index, component := range components {

		// If last component
		if index == len(components)-1 {
			processedkey, validKey := parseKey(component)
			if !validKey {
				return nil, fmt.Errorf("'%s' is not a valid key", component)
			}
			result.X名称 = processedkey
			continue
		}

		// 不是最后一个组件 - 需要作为修饰符
		lowercaseComponent := strings.ToLower(component)
		thisModifier, valid := modifierMap[lowercaseComponent]
		if !valid {
			return nil, fmt.Errorf("'%s' is not a valid modifier", component)
		}
		// Needs to be unique
		if modifiersProcessed.Contains(lowercaseComponent) {
			return nil, fmt.Errorf("Modifier '%s' is defined twice for shortcut: %s", component, shortcut)
		}

		// Save this data
		result.X修饰符 = append(result.X修饰符, thisModifier)
		modifiersProcessed.Add(lowercaseComponent)
	}

	return &result, nil
}
